/*
  中点法画椭圆形
  依旧是通过绘制椭圆形公式找出增量函数
*/
#include "OpenGLCase6.h"

/// <summary>
/// 
/// </summary>
/// <param name="a">长半轴，椭圆的宽/2</param>
/// <param name="b">短半轴，椭圆的高/2</param>
/// <param name="hdc"></param>
void drawEllipse(int cx, int cy, int a, int b, HDC hdc) {
	// 椭圆的隐式方程公式：F(x, y) = b２x２+a２y２-a２b２
	// F(x, y) > 0 点在椭圆外 F(x, y) = 0 点在椭圆上 F(x, y) < 0 点在椭圆内
	// 椭圆在四象限上是对称的，所以没有办法想圆那样八分，只能四分
	// 如果点在第一象限内的上半弧
	// 那么求的增量d = 新d - 旧d = b２(2xi+3) + a２(-2yi+2)
	// 那么d的初值 d =  b２+ a２(-b+0.25)２
	// 如果点在第一象限的下半弧
	// 那么求的增量 d>0 则 d = 新d - 旧d = a２(-2yi+3)
	// 那么求的增量 d<=0 则 d = 新d - 旧d =  b２(2xi+2) + a２(-2yi+3)
	// 那么d的初值 d =  b２(x+0.5) + a２(y-1)２ - a２b２
	// 
	// 上下半弧判定 2a２(yi-0.5) > 2b２(xi+1) 则在上半弧， 2a２(yi-0.5) < 2b２(xi+1) 则在下半弧

	int x = 0, y = b;

	float d1 = b * b + a * a * (-b + 0.25);
	float d2 = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
	
	for (; y > 0;) {

		SetPixel(hdc, x + cx, y + cy, RGB(255, 255, 0));
		SetPixel(hdc, -x + cx, y + cy, RGB(255, 255, 0));
		SetPixel(hdc, x + cx, -y + cy, RGB(255, 255, 0));
		SetPixel(hdc, -x + cx, -y + cy, RGB(255, 255, 0));

		if (2 * a * a * (y - 0.5) > 2 * b * b * (x + 1)) {
			// 上半部分绘制
			if (d1 <= 0) {
				d1 = d1 + b * b * (2 * x + 3);
				x++;
			} else {
				d1 = d1 + b * b * (2 * x + 3) + a * a * (-2 * y + 2);
				x++;
				y--;
			}
		} else {
			// 下半部分
			if (d2 <= 0) {
				d2 = d2 + b * b * (2 * x + 2) + a * a * (-2 * y + 3);
				x++;
				y--;
			}
			else {
				d2 = d2 + a * a * (-2 * y + 3);
				y--;
			}
		}
		
	}
}

void runCase6() {
	// 获取一个可供画图的DC，我这里就直接用桌面算了
	HDC hdc = GetWindowDC(GetDesktopWindow());

	drawEllipse(200, 200, 50, 40, hdc);
}